import 'dart:convert';
import 'package:aichat_flutter_wallet/kai_print.dart';
import 'package:aichat_flutter_wallet/module_common/mpc_help/chainListTool.dart';
import 'package:crypto/crypto.dart';
import 'package:aichat_flutter_wallet/module_common/network/rpc.dart';
import 'package:lib_database/lib_database.dart';
import 'package:lib_network/lib_network.dart';
import 'package:lib_util/log/log.dart';
import 'package:lib_util/utils/utils.dart';
import 'package:lib_web3/lib_web3_method.dart';

import 'http_api.dart';

class RPCHttp {
  RPCHttp._privateConstructor();

  static final RPCHttp _instance = RPCHttp._privateConstructor();

  factory RPCHttp() {
    return _instance;
  }

  String? dataUpdateTime;
  static const String leleApiDomain =
      Config.dexEnvProduct ? 'dex.ompchain.top' : 'spot.ompchain.top';

  init() {
  }

  Future refreshTokenListFast(
      WalletInfo info, List<Token> tokenList, Token nativeToken) async {
    if (tokenList.length <= 0) {
      return;
    }
    //  刷新 币种 列表数据
    Chain chain = info.getChain()!;
    String chainId = chain.evmInfo!.chainId.toString();
    List list = [];

    List<Token20Bean> token20ListFromServer =
        list.map((e) => Token20Bean.fromJson(e)).toList();

    if (token20ListFromServer.length <= 0 ||
        nativeToken.symbol != token20ListFromServer[0].symbol) {
      return;
    }

    Token20Bean nToken = token20ListFromServer[0];

    nativeToken.balance = nToken.balance;
    nativeToken.decimals = nToken.decimals;
    nativeToken.priceusd = nToken.priceUsd;
    nativeToken.valueusd = nToken.valueUsd;

    ObjectBox().tokenModel.updateToken(nativeToken);

    token20ListFromServer.removeAt(0);

    for (int i = 0; i < token20ListFromServer.length; i++) {
      tokenList[i].name = token20ListFromServer[i].name;
      tokenList[i].symbol = token20ListFromServer[i].symbol;
      tokenList[i].balance = token20ListFromServer[i].balance;
      tokenList[i].decimals = token20ListFromServer[i].decimals;
      tokenList[i].priceusd = token20ListFromServer[i].priceUsd;
      tokenList[i].valueusd = token20ListFromServer[i].valueUsd;
    }

    ObjectBox().tokenModel.putTokenList(tokenList);
  }

  Future<Map<String, dynamic>> getTokenListIncreaseU(
      List<String> symbols) async {
    Map<String, dynamic> result = {};
    for (var item in symbols) {
      result[item] = {
        "symbol": item,
        "priceU": '0',
        "change": '0',
      };
    }
    try {
      Response<dynamic> resp = await HttpManager()
          .dio
          .get(API.getBNExchangeRate, queryParameters: {"symbols": symbols});
      // print('getTokenListIncreaseU resp ${resp}');
      var data = [];
      if (resp.data is String) {
        data = json.decode(resp.data);
      } else {
        data = resp.data as List<dynamic>;
      }
      for (var item in data) {
        if (symbols.contains('${item['symbol']}')) {
          result['${item['symbol']}'] = {
            "symbol": item['symbol'],
            "priceU": item['lastPrice'],
            "change": '${item['priceChangePercent']}',
          };
        }
      }
      // print('getBNExchangeRate  ${result}');
    } catch (e) {
      // print('getTokenListIncreaseU error:  ${e}');
      var resp =
          await HttpManager().post(API.getExchangeRate, {"symbols": symbols});
      if (resp?.code == HttpConfig().successCode) {
        // print(' resp!.data  ${resp!.data}');
        for (var item in resp!.data['rate']) {
          result['${item['symbol']}'] = {
            "symbol": item['symbol'],
            "priceU": item['price'],
            "change":
                '${(double.parse(item['change']) / 100).toStringAsFixed(2)}',
          };
        }
      }
    }
    return result;
  }

  // 目前只支持 以太
  Future<Map<String, dynamic>> requestTokenList(WalletInfo walletInfo) async {
    Chain c = walletInfo.getChain()!;
    String? balance = null;
    String? priceU = null;
    String? tokenChange24h = null;
    String rpc = ObjectBox().nodeInfoModel.getSelectedNodeInfo(c.shortName).url;
    balance = await ChainListTool.getMainTokenBalance(c.evmInfo!.chainId,rpc,walletInfo.address);
    kaiPrint('user address : ${walletInfo.address} balance $balance');
    return {
      "chainFullName": c.name,
      "chainShortName": c.shortName,
      "tokenSymbol": c.symbol,
      "holdingAmount": balance,
      "tokenPriceUsd": priceU,
      "tokenChange24h": tokenChange24h,
      "tokenList": {"token_20": [], "token_721": [], "token_1155": []}
    };
  }

  Future<Token> requestTokenItemList(
      WalletInfo walletInfo, Token tokenItem) async {
    Chain c = walletInfo.getChain()!;
    var rpc =
        await ObjectBox().nodeInfoModel.getSelectedNodeInfo(c.shortName).url;
    String? balance = await ChainListTool.getTokenBalance(
      rpc,
      tokenItem.contract,
      walletInfo.address,
      decimals: tokenItem.decimals,chainId:c.evmInfo!.chainId);
    kaiPrint('getTokenBalance $balance');
    tokenItem.balance=balance;
    return tokenItem;
  }


  String generateMD5(str) {
    return md5.convert(utf8.encode(str)).toString();
  }
}
